/*
***********************************************************************
* DataSerialization.h:
* encode and decode data based on IEEE-754 format
* This header file can be read by C compilers
*
*  by Hu.ZH(CrossOcean.ai)
***********************************************************************
*/

#ifndef _DATASERIALIZATION_H_
#define _DATASERIALIZATION_H_

#include <ctype.h>
#include <inttypes.h>
#include <stdarg.h>
#include <string.h>
#include "CRC.h"

/*
** pack754() -- pack a floating point number into IEEE-754 format
*/
uint64_t pack754(double f, unsigned bits, unsigned expbits);

/*
** unpack754() -- unpack a floating point number from IEEE-754 format
*/
double unpack754(uint64_t i, unsigned bits, unsigned expbits);

/*
** packi16() -- store a 16-bit int into a char buffer (like htons())
*/
void packi16(uint8_t *buf, uint16_t i);

/*
** packi32() -- store a 32-bit int into a char buffer (like htonl())
*/
void packi32(uint8_t *buf, uint32_t i);

/*
** packi64() -- store a 64-bit int into a char buffer (like htonl())
*/
void packi64(uint8_t *buf, uint64_t i);

/*
** unpacki16() -- unpack a 16-bit int from a char buffer (like ntohs())
*/
int16_t unpacki16(const uint8_t *buf);

/*
** unpacku16() -- unpack a 16-bit unsigned from a char buffer (like ntohs())
*/
uint16_t unpacku16(const uint8_t *buf);

/*
** unpacki32() -- unpack a 32-bit int from a char buffer (like ntohl())
*/
int32_t unpacki32(const uint8_t *buf);

/*
** unpacku32() -- unpack a 32-bit unsigned from a char buffer (like ntohl())
*/
uint32_t unpacku32(const uint8_t *buf);

/*
** unpacki64() -- unpack a 64-bit int from a char buffer (like ntohl())
*/
int64_t unpacki64(const uint8_t *buf);

/*
** unpacku64() -- unpack a 64-bit unsigned from a char buffer (like ntohl())
*/
uint64_t unpacku64(const uint8_t *buf);

/*
** pack() -- store data dictated by the format string in the buffer
**
**   bits |signed   unsigned   float   string
**   -----+----------------------------------
**      8 |   c        C
**     16 |   h        H
**     32 |   l        L         d
**     64 |   q        Q         g
**      - |                               s
**
**  (16-bit unsigned length is automatically prepended to strings)
*/
int16_t pack(uint8_t *buf, const char *format, ...);

/*
** unpack() -- unpack data dictated by the format string into the buffer
**
**   bits |signed   unsigned   float   string
**   -----+----------------------------------
**      8 |   c        C
**     16 |   h        H         f
**     32 |   l        L         d
**     64 |   q        Q         g
**      - |                               s
**
**  (string is extracted based on its stored length, but 's' can be
**  prepended with a max length)
*/
void unpack(const uint8_t *buf, const char *format, ...);

// calcuate the Modbus crc
uint16_t CRC16(const uint8_t *nData, uint16_t wLength);

#endif /* _DATASERIALIZATION_H_ */
